package simulador;



import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


import eduni.simjava.Sim_stat;
import eduni.simjava.Sim_system;


public class Simulador {
	
	
    private List<Carro> carros;
	private Locadora locadora;


	public Simulador(double taxaDeChegadaEmHora, double tempoDeAluguelEmDias,
			int numeroDeCarros, double tempoDeAtendimentoEmHora, double confidenceLavel, 
			double accuracy) {
    	
    	Sim_system.initialise();
    	
    	FonteDeClientes fonteDeClientes = new FonteDeClientes(taxaDeChegadaEmHora);
    	locadora = new Locadora(numeroDeCarros, tempoDeAtendimentoEmHora);
    	
    	carros = new ArrayList<Carro>();
    	for (int numeroDoCarro = 0; numeroDoCarro < numeroDeCarros; numeroDoCarro++) {
    		carros.add(new Carro(numeroDoCarro,tempoDeAluguelEmDias));
    	}
    	
    	Sim_system.link_ports(FonteDeClientes.NOME_DA_ENTIDADE, 
    			FonteDeClientes.PORTA_DE_SAIDA, Locadora.NOME_DA_ENTIDADE, 
    			Locadora.PORTA_DE_ENTRADA);
    	for (int numeroDoCarro = 0; numeroDoCarro < carros.size(); numeroDoCarro++) {
    		Carro carro = carros.get(numeroDoCarro);
    		Sim_system.link_ports(Locadora.NOME_DA_ENTIDADE, 
    				Locadora.PREFIXO_DE_PORTA_DE_SAIDA + numeroDoCarro, carro.get_name(), 
    				Carro.PORTA_DE_ENTRADA);	
    	}
    	
    	Sim_system.set_trace_detail(false, true, false);
    	//Sim_system.set_transient_condition(Sim_system.TIME_ELAPSED, Math.round(accuracy * 0.2));
    	//Sim_system.set_termination_condition(Sim_system.TIME_ELAPSED, numeroDeDias, false);
    	Sim_system.set_termination_condition(Sim_system.INTERVAL_ACCURACY,
    			Sim_system.IND_REPLICATIONS,
    			confidenceLavel,
    			accuracy,
    			Locadora.NOME_DA_ENTIDADE,
    			Sim_stat.UTILISATION);
    	
    	Sim_system.generate_graphs(true);
    	Sim_system.set_report_detail(true, true);
	}
    
    public void rodarSimulador(){
    	Sim_system.run();
    }
    
    
    public int getNumeroDeChegadas(){    	
    	return locadora.get_stat().count(Sim_stat.ARRIVAL_RATE);
    }
    
    public int getClientesAtendidos(){    	
    	return locadora.get_stat().count(Locadora.STAT_CLIENTES_ATENDIDOS);
    }

    public int getAlugueisDeCarro(){    	
    	return locadora.get_stat().count(Locadora.STAT_ALUGUEIS_DE_CARRO);
    }

    public int getSaidasSemCarro(){    	
    	return locadora.get_stat().count(Locadora.STAT_SAIDAS_SEM_CARRO);
    }
    
    public double getDiasDeSimulacao(){
    	Scanner sc;
		try {
			sc = new Scanner(new File("sim_report"));
			String linha = sc.nextLine();
			while(!linha.startsWith("Total simulated time")){
				linha = sc.nextLine();
			}
			
			String[] tokens = linha.split(" ");
			return Math.round(Double.parseDouble(tokens[tokens.length - 1]) / 24);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
    	return Double.MIN_VALUE;
    }
    
    public List<Integer> getNumeroDeClientesPorCarro(){
    	List<Integer> numeros = new ArrayList<Integer>();
    	for (Carro carro : carros) {
			numeros.add(carro.get_stat().count(Sim_stat.ARRIVAL_RATE));
		}
    	return numeros;
    }
    
    public List<Double> getTempoMedioDeAluguelPorCarro(){
    	List<Double> numeros = new ArrayList<Double>();
    	for (Carro carro : carros) {
			numeros.add(carro.get_stat().average(Sim_stat.SERVICE_TIME));
		}
    	return numeros;
    }
}
